﻿#region 文件信息

// FileName: SoCafeShop/Sohobloo.SoAuth.Web/FunctionController.cs
// Author: Sohobloo
// CreateTime: 2013/06/30 5:23
// UpdateTime: 2013/07/01 5:32

#endregion

#region 引用

using System;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web.Mvc;
using Sohobloo.SoAuth.Entity;
using Sohobloo.SoAuth.Service;
using Sohobloo.SoAuth.Web.Models;

#endregion

namespace Sohobloo.SoAuth.Web.Controllers
{
    [Export]
    public class FunctionController : Controller
    {
        #region 属性

        [Import]
        public IFunctionService FunctionService { get; set; }

        #endregion 属性

        #region 方法

        /// <summary>
        ///     新增页面
        /// </summary>
        /// <returns></returns>
        public ActionResult Add()
        {
            //创建新的Function模型
            var functionModel = new FunctionModel();

            //创建父级Function下拉框
            var parentFunctionList = FunctionService.GetFunctionList().Select(
                f => new
                {
                    ParentFunctionId = f.Id as Guid?,
                    ParentFunctionName = f.FunctionName
                }).ToList();
            parentFunctionList.Insert(
                0,
                new
                {
                    ParentFunctionId = null as Guid?,
                    ParentFunctionName = "请选择"
                });
            var parentFunctionSelectList = new SelectList(
                parentFunctionList, "ParentFunctionId", "ParentFunctionName", null);
            ViewBag.FunctionList = parentFunctionSelectList;

            return View(functionModel);
        }

        /// <summary>
        ///     新增Function操作
        /// </summary>
        /// <param name="functionModel"></param>
        /// <returns></returns>
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Add(FunctionModel functionModel)
        {
            //根据Function模型创建新的Function实体
            var function = new SoAuthFunction
            {
                FunctionName = functionModel.FunctionName.Trim(),
                FunctionEnabled = functionModel.FunctionEnabled,
                IgnoreControl = functionModel.IgnoreControl,
                InMenu = functionModel.InMenu,
                MenuOrder = functionModel.MenuOrder,
            };
            if(functionModel.ParentFunctionId.HasValue)
            {
                //设置Function的父级Function
                function.ParentFunction = FunctionService.GetFunction(functionModel.ParentFunctionId.Value);
            }
            //设置Function的参数列表
            SetFunctionParams(function, functionModel);

            //执行Function实体新增
            FunctionService.CreateFunction(function);

            //执行成功转到
            return RedirectToAction("Index");
        }

        /// <summary>
        ///     删除Function操作
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Delete(Guid id)
        {
            //执行Function实体删除
            FunctionService.DeleteFunction(id);

            //刷新页面
            return RedirectToAction("Index");
        }

        /// <summary>
        ///     编辑Function页面
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Edit(Guid id)
        {
            var function = FunctionService.GetFunction(id);
            var functionModel = new FunctionModel
            {
                FunctionEnabled = function.FunctionEnabled,
                FunctionUrl = GetFunctionUrl(function),
                FunctionName = function.FunctionName,
                IgnoreControl = function.IgnoreControl,
                InMenu = function.InMenu,
                MenuOrder = function.MenuOrder
            };
            if(function.ParentFunction != null)
            {
                functionModel.ParentFunctionId = function.ParentFunction.Id;
                functionModel.ParentFunctionName = function.ParentFunction.FunctionName;
            }
            var parentFunctionList = FunctionService.GetFunctionList().Where(f => f.Id != id).Select(
                f => new
                {
                    ParentFunctionId = f.Id as Guid?,
                    ParentFunctionName = f.FunctionName
                }).ToList();
            parentFunctionList.Insert(
                0,
                new
                {
                    ParentFunctionId = null as Guid?,
                    ParentFunctionName = "请选择"
                });
            var parentFunctionSelectList = new SelectList(
                parentFunctionList,
                "ParentFunctionId",
                "ParentFunctionName",
                function.ParentFunction != null ? function.ParentFunction.Id : null as Guid?);
            ViewBag.FunctionList = parentFunctionSelectList;

            return View(functionModel);
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Edit(FunctionModel functionModel)
        {
            var function = FunctionService.GetFunction(functionModel.Id);
            function.FunctionName = functionModel.FunctionName.Trim();
            function.FunctionEnabled = functionModel.FunctionEnabled;
            function.IgnoreControl = functionModel.IgnoreControl;
            function.InMenu = functionModel.InMenu;
            function.MenuOrder = functionModel.MenuOrder;
            if (functionModel.ParentFunctionId.HasValue)
            {
                function.ParentFunction = FunctionService.GetFunction(functionModel.ParentFunctionId.Value);
            }
            else if(function.ParentFunction != null)
            {
                function.ParentFunction.ChildrenFunctions.Remove(function);
                function.ParentFunction = null;
            }
            SetFunctionParams(function, functionModel);

            FunctionService.UpdateFunction(function);

            return RedirectToAction("Index");
        }

        private static void SetFunctionParams(SoAuthFunction function, FunctionModel functionModel)
        {
            if(!string.IsNullOrWhiteSpace(functionModel.FunctionUrl) && functionModel.FunctionUrl.Contains("?"))
            {
                var splitUrl = functionModel.FunctionUrl.Trim().Split('?');
                function.FunctionPath = splitUrl[0];
                if(splitUrl.Length == 2 && !string.IsNullOrWhiteSpace(splitUrl[1]))
                {
                    function.FunctionParams = new Collection<SoAuthFunctionParam>();
                    var splitParams = splitUrl[1].Split('&');
                    foreach(var param in splitParams)
                    {
                        var splitParam = param.Split('=');
                        if(!string.IsNullOrWhiteSpace(splitParam[0]))
                        {
                            var funtionParam = new SoAuthFunctionParam();
                            funtionParam.ParamName = splitParam[0];
                            if(splitParam.Length == 2 && !string.IsNullOrWhiteSpace(splitParam[1]))
                            {
                                funtionParam.ParamValue = splitParam[1];
                            }
                            function.FunctionParams.Add(funtionParam);
                        }
                    }
                }
            }
            else
            {
                function.FunctionPath = functionModel.FunctionUrl != null ? functionModel.FunctionUrl.Trim() : null;
            }
        }

        private static string GetFunctionUrl(SoAuthFunction function)
        {
            var functionUrl = function.FunctionPath;
            if(function.FunctionParams != null && function.FunctionParams.Any())
            {
                functionUrl += "?"
                    + string.Join(
                        "&",
                        function.FunctionParams.Select(
                            fp =>
                                fp.ParamName
                                    + (string.IsNullOrWhiteSpace(fp.ParamValue) ? string.Empty : ("=" + fp.ParamValue))));
            }
            return functionUrl;
        }

        public ActionResult Index()
        {
            var functionList = FunctionService.GetFunctionList();

            var functionModelList = functionList.Select(
                f => new FunctionModel
                {
                    Id = f.Id,
                    FunctionEnabled = f.FunctionEnabled,
                    FunctionUrl = GetFunctionUrl(f),
                    FunctionName = f.FunctionName,
                    IgnoreControl = f.IgnoreControl,
                    InMenu = f.InMenu,
                    MenuLevel = f.MenuLevel,
                    MenuOrder = f.MenuOrder,
                    ParentFunctionName = f.ParentFunction != null ? f.ParentFunction.FunctionName : string.Empty,
                });

            return View(functionModelList);
        }

        #endregion 方法
    }
}